﻿using System;
using System.Linq;
using System.Windows;
using ALiteTeam.PackageTracer.Core;
using ALiteTeam.PackageTracer.Core.Impl;
using ALiteTeam.PackageTracer.Data;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using GalaSoft.MvvmLight.Messaging;
using Microsoft.Phone.Shell;

namespace ALiteTeam.PackageTracer.ViewModel
{
    public class DeliveryOrderSubViewModel : ViewModelBase
    {
        private DeliveryOrder _Order;
        private Delivery _Delivery;

        public IDeliveryOperate DeliveryOp { get; set; }
        public IOrderOperate OrderOp { get; set; }
        public IQueryService QueryOp { get; set; }

        public DeliveryOrder Order { get { return _Order; } }

        /// <summary>
        /// 当前ViewModel唯一标识DeliveryOrderID
        /// </summary>
        public Guid OrderID { get { return _Order.DeliveryOrderID; } }

        public DeliveryOrderSubViewModel(DeliveryOrder order)
        {
            if (this.IsInDesignMode == false)
            {
                _Order = order;

                this.DeliveryOp = DeliveryDataOp.Instance;
                this.OrderOp = new OrderOp();
                this.QueryOp = new QuerySvcOp(_Order);
                this.QueryOp.QuerySummaryCompleted += new EventHandler<QueryEventArgs>(QueryOp_QuerySummaryCompleted);

                _Delivery = this.DeliveryOp.DeliveryResource.Deliveries.Where(e => e.ID == _Order.DeliveryID).FirstOrDefault();

                this.DisplayName = _Delivery.DisplayName;

                this.OrderNo = _Order.OrderNo;
                this.Title = _Order.Title;
                this.IsAvailableToPin = !TileHandler.Exists(_Order);

                #region 为SummaryInfo属性赋值
                if (string.IsNullOrEmpty(_Order.Summary) == false)
                {
                    QueryResult result = QueryResult.ParseOrder(_Order.Summary);

                    // 根据状态信息返回摘要信息
                    switch (result.Status)
                    {
                        // 未查到单据
                        case 0:
                            {
                                this.SummaryInfo = "\r\n运单尚未登记过或已过期";
                                break;
                            }
                        // 成功查询
                        case 1:
                            {
                                if (result.Details[0] != null && result.Details.Count > 0)
                                {
                                    this.SummaryInfo = string.Format("{0}\r\n{1}", result.Details[0].Time, result.Details[0].Context);
                                }
                                else
                                {
                                    this.SummaryInfo = "\r\n" + result.Summary;
                                }
                                break;
                            }
                        // 验证码失败
                        case 4:
                            {
                                this.SummaryInfo = "\r\n提交验证码失败";
                                break;
                            }
                        // 未定义错误
                        case 2:
                        case 3:
                        default:
                            {
                                this.SummaryInfo = "\r\n网络故障，请稍候重试";
                                break;
                            }
                    }
                }
                #endregion

                this.DeleteCommand = new RelayCommand<System.Windows.Input.GestureEventArgs>(Delete);
                this.RefreshCommand = new RelayCommand<System.Windows.Input.GestureEventArgs>(Refresh);
                this.InitializeCommand = new RelayCommand(Initialize, () => { return !_Order.LastSummaryUpdatedTime.HasValue; });

                this.NavigateCommand = new RelayCommand(Navigate);
                this.PinCommand = new RelayCommand(Pin);
            }
        }

        void QueryOp_QuerySummaryCompleted(object sender, QueryEventArgs e)
        {
            // 若查询操作没发生异常（仅指HTTP访问操作）
            if (e.Success == true && string.IsNullOrEmpty(e.Result) != true)
            {
                // 如果发现此次返回值与上一次的值不同，则更新
                if (_Order.Summary != e.Result)
                {
                    this._Order.Summary = e.Result;
                }

                // 但每次刷新都会保存最后更新时间字段
                this._Order.LastSummaryUpdatedTime = DateTime.Now;
                this.OrderOp.UpdateOrder(_Order);

                QueryResult result;
                try
                {
                    result = QueryResult.ParseOrder(e.Result);
                }
                catch
                {
                    result = new QueryResult()
                    {
                        Status = 99
                    };
                }

                switch(result.Status)
                {
                    // 未查到单据
                    case 0:
                        {
                            this.SummaryInfo = "\r\n运单尚未登记过或已过期";
                            break;
                        }
                    // 成功查询
                    case 1:
                        {
                            if (result.Details[0] != null && result.Details.Count > 0)
                            {
                                this.SummaryInfo = string.Format("{0}\r\n{1}", result.Details[0].Time, result.Details[0].Context);
                            }
                            else
                            {
                                this.SummaryInfo = "\r\n" + result.Summary;
                            }
                            break;
                        }
                    // 验证码失败
                    case 4:
                        {
                            this.SummaryInfo = "\r\n提交验证码失败";
                            break;
                        }
                    case 99:
                        {
                            this.SummaryInfo = "\r\n接收到的数据转换失败，请联系开发者更新API";
                            break;
                        }
                    default:
                        {
                            this.SummaryInfo = "\r\n网络故障，请稍候重试";
                            break;
                        }
                }
            }
            else
            {
                this.SummaryInfo = "\r\n网络故障，请稍候重试";
            }

            // 通知重新获取最后更新时间属性
            RaisePropertyChanged(LastUpdatedTipPropertyName);
        }

        #region 绑定属性
        /// <summary>
        /// The <see cref="OrderNo" /> property's name.
        /// </summary>
        public const string OrderNoPropertyName = "OrderNo";
        private string mOrderNo = string.Empty;

        /// <summary>
        /// Gets the OrderNo property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string OrderNo
        {
            get
            {
                return mOrderNo;
            }
            set
            {
                if (mOrderNo == value)
                {
                    return;
                }
                mOrderNo = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(OrderNoPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="IsAvailableToPin" /> property's name.
        /// </summary>
        public const string IsAvailableToPinPropertyName = "IsAvailableToPin";
        private bool mIsAvailableToPin = true;

        /// <summary>
        /// Gets the IsAvailableToPin property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public bool IsAvailableToPin
        {
            get
            {
                return mIsAvailableToPin;
            }
            set
            {
                if (mIsAvailableToPin == value)
                {
                    return;
                }
                mIsAvailableToPin = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(IsAvailableToPinPropertyName);
            }
        }

        /// <summary>
        /// The <see cref="Title" /> property's name.
        /// </summary>
        public const string TitlePropertyName = "Title";

        private string mTitle = string.Empty;

        /// <summary>
        /// Gets the Title property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string Title
        {
            get
            {
                return mTitle;
            }

            set
            {
                if (mTitle == value)
                {
                    return;
                }
                mTitle = value;
                // Update bindings, no broadcast
                RaisePropertyChanged(TitlePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="DisplayName" /> property's name.
        /// </summary>
        public const string DisplayNamePropertyName = "DisplayName";

        private string mDisplayName = string.Empty;

        /// <summary>
        /// Gets the DisplayName property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string DisplayName
        {
            get
            {
                return mDisplayName;
            }
            set
            {
                if (mDisplayName == value)
                {
                    return;
                }
                mDisplayName = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(DisplayNamePropertyName);
            }
        }

        /// <summary>
        /// The <see cref="LastUpdatedTip" /> property's name.
        /// </summary>
        public const string LastUpdatedTipPropertyName = "LastUpdatedTip";
        private string mLastUpdatedTip = string.Empty;

        /// <summary>
        /// Gets the LastUpdatedTip property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string LastUpdatedTip
        {
            get
            {
                string message;
                var slice = DateTime.Now - this._Order.LastSummaryUpdatedTime;
                if (slice.HasValue == true)
                {
                    if (slice < TimeSpan.FromSeconds(5))
                    {
                        message = "刚刚更新";
                    }
                    else if (slice < TimeSpan.FromSeconds(60))
                    {
                        message = string.Format("{0}秒前更新", slice.Value.Seconds);
                    }
                    else if (slice < TimeSpan.FromMinutes(60))
                    {
                        message = string.Format("{0}分钟前更新", slice.Value.Minutes);
                    }
                    else if (slice < TimeSpan.FromHours(24))
                    {
                        message = string.Format("{0}小时前更新", slice.Value.Hours);
                    }
                    else
                    {
                        message = string.Format("{0}天前更新", slice.Value.Days);
                    }
                }
                else
                {
                    message = "";
                }

                return message;
            }
        }

        /// <summary>
        /// The <see cref="SummaryInfo" /> property's name.
        /// </summary>
        public const string SummaryInfoPropertyName = "SummaryInfo";
        private string mSummaryInfo = string.Empty;

        /// <summary>
        /// Gets the SummaryInfo property.
        /// TODO Update documentation:
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the Messenger's default instance when it changes.
        /// </summary>
        public string SummaryInfo
        {
            get
            {
                return mSummaryInfo;
            }

            set
            {
                if (mSummaryInfo == value)
                {
                    return;
                }
                mSummaryInfo = value;

                // Update bindings, no broadcast
                RaisePropertyChanged(SummaryInfoPropertyName);
            }
        }

        #endregion

        #region 绑定Command属性以及实现

        public RelayCommand<System.Windows.Input.GestureEventArgs> DeleteCommand { get; private set; }
        private void Delete(System.Windows.Input.GestureEventArgs e)
        {
            var msg = string.Format("是否真的要删除名为{0}的运单？", Title);

            if (MessageBox.Show(msg, "警告", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
            {
                this.OrderOp.DeleteOrder(_Order);
                ViewModelLocator.MainPageViewModelStatic.DeliveryOrders.Remove(this);
                TileHandler.DeleteIile(_Order);
            }

            e.Handled = true;
        }

        public RelayCommand<System.Windows.Input.GestureEventArgs> RefreshCommand { get; private set; }
        private void Refresh(System.Windows.Input.GestureEventArgs e)
        {
            this.SummaryInfo = "\r\n查询中，请稍候...";
            this.QueryOp.GetSummary();

            e.Handled = true;
        }

        public RelayCommand InitializeCommand { get; private set; }
        public void Initialize()
        {
            this.SummaryInfo = "\r\n查询中，请稍候...";
            this.QueryOp.GetSummary();
        }

        public RelayCommand NavigateCommand { get; private set; }
        private void Navigate()
        {
            (Application.Current.RootVisual as Microsoft.Phone.Controls.PhoneApplicationFrame).Navigate(new Uri("/View/Details.xaml", UriKind.Relative));

            // 给Details页面发送消息
            Messenger.Default.Send<Guid>(_Order.DeliveryOrderID, DetailsViewModel.INITIALIZE);
        }

        public RelayCommand PinCommand { get; private set; }
        private void Pin()
        {
            TileHandler.PinIileToScreen(_Order);
            IsAvailableToPin = false;
        }
        #endregion
    }
}